package edu.gatech.cs2340.mule.tests;
//import static org.junit.Assert.*;

import java.awt.Color;
import java.awt.Point;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import edu.gatech.cs2340.mule.model.MuleGame;
import edu.gatech.cs2340.mule.model.Mule;
import edu.gatech.cs2340.mule.model.Player;
import edu.gatech.cs2340.mule.model.Race;
import edu.gatech.cs2340.mule.model.Transaction;
import edu.gatech.cs2340.mule.model.Store;
import edu.gatech.cs2340.mule.model.StoreInterface;
import edu.gatech.cs2340.mule.model.LandOffice;
import edu.gatech.cs2340.mule.model.LandOfficeInterface;
import edu.gatech.cs2340.mule.model.Pub;
import edu.gatech.cs2340.mule.model.PubInterface;
import edu.gatech.cs2340.mule.model.TurnEngine;

public class TransactionTest {
	Store gameStore;
	StoreInterface gameStoreInterface;
	LandOffice landOffice;
	LandOfficeInterface landOfficeInterface;
	Pub pub;
	PubInterface pubInterface;
	Player player;
	MuleGame game;
	TurnEngine engine;
	@Before
	public void setUp(){
		player = new Player(Color.BLUE, "James T. Kirk", new Race("Human")); // Creates the player
		Player[] players = new Player[1];
		players[0] = player;
		game  = new MuleGame(players,"Classic", "Beginner");
		gameStore = new Store();
		gameStoreInterface = new StoreInterface(gameStore);
		landOffice = new LandOffice();
		landOfficeInterface = new LandOfficeInterface(game,landOffice);
		pub = new Pub();
		engine = new TurnEngine(players);
		pubInterface = new PubInterface(game, pub, engine);
		
	}
	
	@Test
	public void buyEnergyTest(){		
		player.setEnergyAmount(-50);
		player.setMoneyAmount(-5000);
		player.setMoneyAmount(500);
		
		boolean bol = Transaction.buyEnergyFromStore(gameStoreInterface, player, 2);
		
		Assert.assertEquals(bol, true);
		Assert.assertEquals(player.getMoneyAmount(), 450);
		Assert.assertEquals(player.getEnergyAmount(), 2);
	}
	
	@Test
	public void noMoneyBuyEnergyTest(){
		player.setEnergyAmount(-50);		
		player.setMoneyAmount(-10000); //Makes sure player has no money
		
		boolean bol = Transaction.buyEnergyFromStore(gameStoreInterface, player, 2);
		
		Assert.assertEquals(bol, false);
		Assert.assertEquals(player.getMoneyAmount(), 0);
		Assert.assertEquals(player.getEnergyAmount(), 0);		
	}
	
	@Test 
	public void buyFoodTest(){
		player.setFoodAmount(-50);	
		player.setMoneyAmount(-10000); //Makes sure player has no money
		player.setMoneyAmount(500);
		
		boolean bol = Transaction.buyFoodFromStore(gameStoreInterface, player, 2);
		
		Assert.assertEquals(bol, true);
		Assert.assertEquals(player.getMoneyAmount(), 440);
		Assert.assertEquals(player.getFoodAmount(), 2);
	}
	
	@Test
	public void noMoneyBuyFoodTest(){
		player.setFoodAmount(-50);		
		player.setMoneyAmount(-10000); //Makes sure player has no money
		
		boolean bol = Transaction.buyFoodFromStore(gameStoreInterface, player, 2);
		
		Assert.assertEquals(bol, false);
		Assert.assertEquals(player.getMoneyAmount(), 0);
		Assert.assertEquals(player.getFoodAmount(), 0);		
	}
	
	@Test 
	public void buySmithoreTest(){
		player.setSmithOreAmount(-50);	
		player.setMoneyAmount(-10000); //Makes sure player has no money
		player.setMoneyAmount(500);
		
		
		boolean bol = Transaction.buySmithoreFromStore(gameStoreInterface, player, 2);
		
		Assert.assertEquals(bol, false);
		Assert.assertEquals(player.getMoneyAmount(), 500);
		Assert.assertEquals(player.getSmithOreAmount(), 0);
	}
	
	@Test
	public void noMoneyBuySmithoreTest(){
		player.setSmithOreAmount(-50);		
		player.setMoneyAmount(-10000); //Makes sure player has no money
		
		boolean bol = Transaction.buySmithoreFromStore(gameStoreInterface, player, 2);
		
		Assert.assertEquals(bol, false);
		Assert.assertEquals(player.getMoneyAmount(), 0);
		Assert.assertEquals(player.getSmithOreAmount(), 0);		
	}
	
	@Test 
	public void buyEnergyMuleTest(){
		Mule mule;
		player.setMoneyAmount(-10000); //Makes sure player has no money
		player.setMoneyAmount(500);
		
		mule = Transaction.buyMuleFromStore(gameStoreInterface, player, "ENERGY");
		
		Assert.assertEquals("ENERGY", mule.getType());
		Assert.assertEquals(player.getMoneyAmount(), 350);
	}
	
	@Test 
	public void noMoneyBuyEnergyMuleTest(){
		Mule mule;
		player.setMoneyAmount(-10000);
		
		mule = Transaction.buyMuleFromStore(gameStoreInterface, player, "ENERGY");
		
		Assert.assertEquals(null, mule);
		Assert.assertEquals(player.getMoneyAmount(), 0);
	}
	
	@Test 
	public void buyFoodMuleTest(){
		Mule mule;
		player.setMoneyAmount(-10000); //Makes sure player has no money
		player.setMoneyAmount(500);
		
		mule = Transaction.buyMuleFromStore(gameStoreInterface, player, "FOOD");
		
		Assert.assertEquals("FOOD", mule.getType());
		Assert.assertEquals(player.getMoneyAmount(), 370);
	}
	
	@Test 
	public void noMoneyBuyFoodMuleTest(){
		Mule mule;
		player.setMoneyAmount(-10000);
		
		mule = Transaction.buyMuleFromStore(gameStoreInterface, player, "FOOD");
		
		Assert.assertEquals(null, mule);
		Assert.assertEquals(player.getMoneyAmount(), 0);
	}
	
	@Test 
	public void buySmithoreMuleTest(){
		Mule mule;
		player.setMoneyAmount(-10000); //Makes sure player has no money
		player.setMoneyAmount(500);
		
		mule = Transaction.buyMuleFromStore(gameStoreInterface, player, "SMITHORE");
		
		Assert.assertEquals("SMITHORE", mule.getType());
		Assert.assertEquals(player.getMoneyAmount(), 325);
	}
	
	@Test 
	public void noMoneyBuySmithoreMuleTest(){
		Mule mule;
		player.setMoneyAmount(-10000);
		
		mule = Transaction.buyMuleFromStore(gameStoreInterface, player, "SMITHORE");
		
		Assert.assertEquals(null, mule);
		Assert.assertEquals(player.getMoneyAmount(), 0);
	}
	
	@Test
	public void sellEnergyTest(){
		player.setEnergyAmount(-200);
		player.setEnergyAmount(2);		
		player.setMoneyAmount(-10000);
		
		boolean bol = Transaction.sellEnergyToStore(gameStoreInterface, player, 2);
		
		Assert.assertEquals(bol, true);
		Assert.assertEquals(player.getMoneyAmount(), 50);
		Assert.assertEquals(player.getEnergyAmount(), 0);
	}
	
	@Test
	public void noEnergySellEnergyTest(){
		player.setEnergyAmount(-50);		
		player.setMoneyAmount(-10000);
		
		boolean bol = Transaction.sellEnergyToStore(gameStoreInterface, player, 2);
		
		Assert.assertEquals(bol, false);
		Assert.assertEquals(player.getMoneyAmount(), 0);
		Assert.assertEquals(player.getEnergyAmount(), 0);
	}
	
	@Test
	public void sellFoodTest(){
		player.setFoodAmount(-10000); //Makes sure player has no money
		player.setFoodAmount(2);		
		player.setMoneyAmount(-10000);
		
		boolean bol = Transaction.sellFoodToStore(gameStoreInterface, player, 2);
		
		Assert.assertEquals(bol, true);
		Assert.assertEquals(player.getMoneyAmount(), 60);
		Assert.assertEquals(player.getFoodAmount(), 0);
	}
	
	@Test
	public void noFoodSellFoodTest(){
		player.setFoodAmount(-50);		
		player.setMoneyAmount(-10000);
		
		boolean bol = Transaction.sellFoodToStore(gameStoreInterface, player, 2);
		
		Assert.assertEquals(bol, false);
		Assert.assertEquals(player.getMoneyAmount(), 0);
		Assert.assertEquals(player.getFoodAmount(), 0);
	}
	
	@Test
	public void sellSmithoreTest(){
		player.setSmithOreAmount(-200);
		player.setSmithOreAmount(2);		
		player.setMoneyAmount(-10000);
		
		boolean bol = Transaction.sellSmithoreToStore(gameStoreInterface, player, 2);
		
		Assert.assertEquals(bol, true);
		Assert.assertEquals(player.getMoneyAmount(), 100);
		Assert.assertEquals(player.getSmithOreAmount(), 0);
	}
	
	@Test
	public void noSmithoreSellFoodTest(){
		player.setFoodAmount(-50);		
		player.setMoneyAmount(-10000);
		
		boolean bol = Transaction.sellSmithoreToStore(gameStoreInterface, player, 2);
		
		Assert.assertEquals(bol, false);
		Assert.assertEquals(player.getMoneyAmount(), 0);
		Assert.assertEquals(player.getSmithOreAmount(), 0);
	}
	
	@Test
	public void gambleAtPubTest(){
		player.setMoneyAmount(-100000);
		Transaction.gambleAtPub(pubInterface, player);
		
		Assert.assertTrue(player.getMoneyAmount() > 0);
	}
	
	@Test
	public void buyFromLandOfficeTest(){
		Point p = new Point(0,0);
		if (player.isOwned(p)){
			player.removeOwnedLand(p);
		}
		if (!landOffice.isUnowned(p)){
			landOffice.addUnownedLand(p);
		}
		
		player.setMoneyAmount(-10000);
		player.setMoneyAmount(1000);
		boolean bol = Transaction.buyFromLandOffice(landOfficeInterface, player, p);
		
		Assert.assertEquals(bol, true);
		Assert.assertTrue(player.getMoneyAmount() < 700);
		Assert.assertEquals(player.isOwned(p), true);
		Assert.assertEquals(landOffice.isUnowned(p), false);
		
	}
	
	@Test
	public void noMoneyBuyFromLandOfficeTest(){
		Point p = new Point(0,0);
		if (player.isOwned(p)){
			player.removeOwnedLand(p);
		}
		if (!landOffice.isUnowned(p)){
			landOffice.addUnownedLand(p);
		}
		
		player.setMoneyAmount(-10000);
		boolean bol = Transaction.buyFromLandOffice(landOfficeInterface, player, p);
		
		Assert.assertEquals(bol, false);
		Assert.assertEquals(player.getMoneyAmount(), 0);
		Assert.assertEquals(player.isOwned(p), false);
		Assert.assertEquals(landOffice.isUnowned(p), true);
		
	}
	
	@Test
	public void isAlreadyOwnedTest(){
		Point p = new Point(0,0);
		if (landOffice.isUnowned(p)){
			landOffice.removeUnownedLand(p);
		}
		
		player.setMoneyAmount(-10000);
		player.setMoneyAmount(1000);
		boolean bol = Transaction.buyFromLandOffice(landOfficeInterface, player, p);
		
		Assert.assertEquals(bol, false);
		Assert.assertEquals(player.getMoneyAmount(), 1000);
		Assert.assertEquals(player.isOwned(p), false);
		Assert.assertEquals(landOffice.isUnowned(p), false);
		
		
	}
	
	@Test
	public void sellToLandOfficeTest(){
		Point p = new Point(0,0);
		if (!player.isOwned(p)){
			player.addOwnedLand(p);
		}
		if (landOffice.isUnowned(p)){
			landOffice.removeUnownedLand(p);
		}
		
		player.setMoneyAmount(-10000);
		boolean bol = Transaction.sellToLandOffice(landOfficeInterface, player, p);
		
		Assert.assertEquals(bol, true);
		Assert.assertTrue(player.getMoneyAmount() > 400);
		Assert.assertEquals(player.isOwned(p), false);
		Assert.assertEquals(landOffice.isUnowned(p), true);
	}
	
	@Test
	public void isUnownedSellToLandOfficeTest(){
		Point p = new Point(0,0);
		if (player.isOwned(p)){
			player.removeOwnedLand(p);
		}
		if (!landOffice.isUnowned(p)){
			landOffice.addUnownedLand(p);
		}
		
		player.setMoneyAmount(-10000);
		boolean bol = Transaction.sellToLandOffice(landOfficeInterface, player, p);
		
		Assert.assertEquals(bol, false);
		Assert.assertEquals(player.getMoneyAmount(), 0);
		Assert.assertEquals(player.isOwned(p), false);
		Assert.assertEquals(landOffice.isUnowned(p), true);
	}
	
	
	
}
